package bob.project;
 
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Sound;
import org.newdawn.slick.loading.LoadingList;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
 
public class ResourceManager {
 
	public static boolean loaded = false;
 
	private static  Map<String, Sound> soundMap = new HashMap<String, Sound>();
	private static Map<String, Image> imageMap = new HashMap<String, Image>();
	private static  Map<String, String> textMap= new HashMap<String, String>();
 

	public static void loadResources(InputStream is)
	{
		loadResources(is, false,false);
		//loadSheet(ResourceManager.class.getResourceAsStream("sheet.xml"));
	}
 
	public static void loadResources(InputStream is, boolean deferred,boolean textOnly){
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = null;
		try {
			docBuilder = docBuilderFactory.newDocumentBuilder();
		} catch (ParserConfigurationException e) {

		}
		Document doc = null;
        try {
			doc = docBuilder.parse (is);
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
 
		// normalize text representation
        doc.getDocumentElement ().normalize ();
 
        NodeList listResources = doc.getElementsByTagName("resource");
 
        int totalResources = listResources.getLength();
 
        if(deferred){
        	LoadingList.setDeferredLoading(true);
        }
 
 
        for(int resourceIdx = 0; resourceIdx < totalResources; resourceIdx++){
 
        	Node resourceNode = listResources.item(resourceIdx);
 
        	if(resourceNode.getNodeType() == Node.ELEMENT_NODE){
        		Element resourceElement = (Element)resourceNode;
 
        		String type = resourceElement.getAttribute("type");
        		if (textOnly)
        		{
        			if(type.equals("text"))
        				addElementAsText(resourceElement);
        		}
        		else	
        		{
        		if(type.equals("image")){
        			addElementAsImage(resourceElement);
        		}else if(type.equals("sound")){
        			addElementAsSound(resourceElement);
        		}else if(type.equals("text")){
        			addElementAsText(resourceElement);
        		}else if(type.equals("sprite")){
        			addElementAsSprite(resourceElement);
        		}else if(type.equals("sheet")){
        			loadSheet(resourceElement);
        		}
                loaded = true;
        		}
        	}
        }

	}
 
 
	private static void loadSheet(Element resourceElement)
	{
		Image sheet = loadImage(resourceElement.getAttribute("id"), resourceElement.getTextContent());
		InputStream resourceAsStream = ResourceManager.class.getResourceAsStream(resourceElement.getAttribute("id")+".xml");
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = null;
		try {
			docBuilder = docBuilderFactory.newDocumentBuilder();
		} catch (ParserConfigurationException e) {

		}
		Document doc = null;
        try {
			doc = docBuilder.parse (resourceAsStream);
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
        doc.getDocumentElement ().normalize ();	
        NodeList lisSprites = doc.getElementsByTagName("sprite");
       // Image sheet = getImage("sheet");
        int totalSprites = lisSprites.getLength();
        
        for(int resourceIdx = 0; resourceIdx < totalSprites; resourceIdx++)
        {
        	 
        	Node resourceNode = lisSprites.item(resourceIdx);
        	String name = resourceNode.getAttributes().getNamedItem("n").getNodeValue();
        	int x  =  Integer.parseInt(resourceNode.getAttributes().getNamedItem("x").getNodeValue());
        	int y  =  Integer.parseInt(resourceNode.getAttributes().getNamedItem("y").getNodeValue());
        	int w  =  Integer.parseInt(resourceNode.getAttributes().getNamedItem("w").getNodeValue());
        	int h  =  Integer.parseInt(resourceNode.getAttributes().getNamedItem("h").getNodeValue());
        	Image img  = sheet.getSubImage(x, y, w, h);
        	imageMap.put(name, img);
        	
        }

	}

	private static void addElementAsSprite(Element resourceElement)
	{
		Image sheet = loadImage(resourceElement.getAttribute("id"), resourceElement.getTextContent());
    	int x  =  Integer.parseInt(resourceElement.getAttributes().getNamedItem("x").getNodeValue());
    	int y  =  Integer.parseInt(resourceElement.getAttributes().getNamedItem("y").getNodeValue());
    	int w  =  Integer.parseInt(resourceElement.getAttributes().getNamedItem("w").getNodeValue());
    	int h  =  Integer.parseInt(resourceElement.getAttributes().getNamedItem("h").getNodeValue());
    	Image img  = sheet.getSubImage(x, y, w, h);
    	imageMap.put(resourceElement.getAttribute("id"), img);
	}

	private static void addElementAsText(Element resourceElement)
	{
		loadText(resourceElement.getAttribute("id"), resourceElement.getTextContent());
	}
 
	public static String loadText(String id, String value){
		if(value == null)
			System.out.println("Text resource [" + id + "] has invalid value");
 
		textMap.put(id, value);
 
		return value;
	}
 
	public static String getText(String ID) {
		return textMap.get(ID);
	}
 
	private static void addElementAsSound(Element resourceElement){
		loadSound(resourceElement.getAttribute("id"), resourceElement.getTextContent());
	}
 
	public static Sound loadSound(String id, String path){
 
		Sound sound = null;
 
		try {
			sound = new Sound(path);
		} catch (SlickException e) {
			e.printStackTrace();
		}
 
		soundMap.put(id, sound);
 
		return sound;
	}
 
	public static final Sound getSound(String ID){
		return soundMap.get(ID);
	}
 
 
	private static final void addElementAsImage(Element resourceElement){
		loadImage(resourceElement.getAttribute("id"), resourceElement.getTextContent());
	}
 
	public static Image loadImage(String id, String path){

 
		Image image = null;
		try{
			System.out.println(path);
			image = new Image(path);
		} catch (SlickException e) {

			e.printStackTrace();
		}
 
		
		imageMap.put(id, image);
 
		return image;
	}
 
	public static final Image getImage(String ID){
		return imageMap.get(ID);
	}
 
}